<template>
  <view class="layout_top" :style="[layoutTopMove, layoutHeight]">
    <view class="chatLayout" :style="strHeight">
      <scroll-view scroll-y="true" class="content" :scroll-top="scrollTop" :scroll-with-animation="scorllAnimation"
        :show-scrollbar="false" refresher-enabled @refresherrefresh="reachUp" refresher-background="#eee"
        :refresher-triggered="flagForRefresh" @click="topClick">
        <!--  <view class="chat_item left image">
          <view class="item_img">
            <image src="http://127.0.0.1:3000/api/static/user.jpg" mode="scaleToFill" />
          </view>
          <view class="item_content ">
            <image src="http://127.0.0.1:3000/api/static/png/电路图-[]-1721141026676.png" mode="widthFix" />
            <view class="loading"></view>
          </view>
        </view>
        <view class="chat_item right image">
          <view class="item_content ">
            <image src="http://127.0.0.1:3000/api/static/png/电路图-[]-1721141026676.png" mode="widthFix" />
            <view class="loading"></view>
          </view>
          <view class="item_img">
            <image src="http://127.0.0.1:3000/api/static/user.jpg" mode="scaleToFill" />
          </view>
        </view>
        
        <view class="chat_item left file">
          <view class="item_img">
            <image src="http://127.0.0.1:3000/api/static/user.jpg" mode="scaleToFill" />
          </view>
          <view class="item_content ">
            <view class="item_content_nameSize">
              <text class="name">文件徕卡还贷打算大萨达萨达aaaaaaaaaaaashd大萨达萨达</text>
              <text class="size">2.5KB</text>
            </view>
            <view class="item_content_type">
              <image src="@/static/svg/SVG@1x.svg" mode="widthFix" />
            </view>
          </view>
        </view>
        <view class="chat_item right file">
          <view class="item_content ">
            <view class="item_content_nameSize">
              <text class="name">文件徕卡还贷打算大萨达萨达aaaaaaaaaaaashd大萨达萨达</text>
              <text class="size">2.5KB / 正在上传 30%</text>
              <progress :percent="30" />
            </view>
            <view class="item_content_type">
              <image src="@/static/svg/GIF@1x.svg" mode="widthFix" />
            </view>
          </view>
          <view class="item_img">
            <image src="http://127.0.0.1:3000/api/static/user.jpg" mode="scaleToFill" />
          </view>
        </view>
         -->
        <view :class="['chat_item',
          item.type == 'time' ? 'time' : '',
          item.data?.type == 0 ? 'text' : '',
          item.data?.type == 1 ? 'image' : '',
          item.data?.type == 3 ? 'file' : '',
          item.data?.userID == myID ? 'right' : '',
          item.data?.userID == friendID ? 'left' : '',
          item?.page ? `page${item.page}` : '',
        ]" v-for="(item, index) in msgList" :key="item.data?._id ? item.data._id : item.data">
          {{ item.type == 'time' ? parseTimestamp(+item.data) : '' }}
          <view class="item_img" v-if="!(item.type == 'time') && item.data?.userID == friendID && !(friendID == myID)">
            <image :src="friendAvatar" mode="scaleToFill" @click="toUserInfo('friend')" />
          </view>
          <view class="item_content" v-if="!(item.type == 'time')">
            <text v-if="(item.data.type == '0')">{{ item.data?.message }}</text>
            <img v-if="(item.data.type == '1')" mode="widthFix" @click="previewImage(item.data?.message)"
              v-lazy="item.data?.message" />
            <view class="loader" v-if="(item.data.type == '1') && loadingImg[index] ? loadingImg[index] : false">
            </view>
            <view class="item_content_nameSize" v-if="(item.data.type == '3')" @click="downloadFile(item.data)">
              <text class="name">{{ item.data.fileName }}</text>
              <text
                class="size">{{ item.data.isLoading ? `${formatBytes(item.data?.size)} / 正在传输 ${item.data?.progress}` : `${formatBytes(item.data?.size)}` }}</text>
              <progress v-if="item.data.isLoading" :percent="item.data?.progress" />
            </view>
            <view class="item_content_type" v-if="(item.data.type == '3')" @click="downloadFile(item.data)">
              <image :src="`../../static/svg/${item.data.suffix}@1x.svg`" mode="widthFix" />
            </view>
          </view>
          <view class="item_img" v-if="!(item.type == 'time') && item.data?.userID == myID">
            <image :src="myAvatar" mode="scaleToFill" @click="toUserInfo('my')" />
          </view>
        </view>
      </scroll-view>
      <view class="input" :style="heightForInput" @clic.stop="">
        <view class="input_item">
          <view class="iconfont icon-yuyin"></view>
          <textarea :adjust-position="false" :cursor-spacing="25" :show-confirm-bar="false" @linechange="changeLayout"
            @focus="focusHandler" placeholder="请输入内容" class="input_text" maxlength="280" fixed confirm-type="send"
            :confirm-hold="true" :style="inputHeight" @confirm="confirm" v-model="inputValue" @blur="blurHandler"
            :focus="isFocus" @keyboardheightchange="keyBoardHeightChange" adjust-position="false" />
          <view :class="['iconfont', isOpenMore ? 'icon-jianpan' : 'icon-emoji']" @click.stop="openMore(0)">
          </view>
          <view class="iconfont icon-jia" v-if="!isOpenMore && inputValue.length == 0" @click.stop="openMore(1)"></view>
          <view class="send" v-if="inputValue.length !== 0" @touchstart.prevent.stop="confirm">发送</view>
        </view>
      </view>
    </view>
    <view :class="['menu', isOpenMore ? 'active' : '',]" :style="heightForMore" @click.stop="">
      <scroll-view scroll-x class="menu_slection" :enable-flex="true">
        <view class="slection_all">
          <view :class="['iconfont', 'icon-emoji', selectItem == 0 ? 'active' : '']" @touchstart="select(0)"></view>
          <view :class="['iconfont', 'icon-jia', selectItem == 1 ? 'active' : '']" @touchstart="select(1)"></view>
        </view>
      </scroll-view>
      <scroll-view class="List_scroll" scroll-y @touchmove.prevent.stop="">
        <swiper circular class="swiper-more" :current="selectItem" :duration="50" @change="swiperChange">
          <swiper-item class="emoji">
            <scroll-view :scroll-y="true" style="height: 100%; width: 100%;">
              <view class="scroll_style">
                <view class="scroll_item" v-for="(item, index) in emoji" :key="index" @click="selectEmoji(index)">
                  <img v-lazy="item" mode="scaleToFill" />
                </view>
              </view>
            </scroll-view>
          </swiper-item>
          <swiper-item class="jia">
            <view class="more-function">
              <view class="item ">
                <view class="item_box" @click="openFunction('tupian')">
                  <view class="iconfont icon-shangchuantupian"></view>
                  <view class="text">图片</view>
                </view>
              </view>
              <view class="item ">
                <view class="item_box" @click="openFunction('wenjian')">
                  <view class="iconfont icon-wenjian"></view>
                  <view class="text">文件</view>
                </view>
              </view>
              <view class="item ">
                <view class="item_box" @click="openFunction('paishe')">
                  <view class=" iconfont icon-xiangji"></view>
                  <view class="text">拍摄</view>
                </view>
              </view>
            </view>
          </swiper-item>
        </swiper>
      </scroll-view>
    </view>
  </view>
</template>

<script setup>
import { parseTimestamp } from "@/utils/common.js"
import { onBackPress, onHide, onLoad, onNavigationBarButtonTap, onReady, onShow, onUnload } from "@dcloudio/uni-app";
import { ref, getCurrentInstance, computed, watch, reactive, onUnmounted, nextTick } from "vue";
import { login, sendMsg, closeSocket, initWebsocket } from "../../api/socket.js";
import { getMsgList, getRelation, uploadFile, getFile, getUserInfo, clearUnread, fileIsFound } from "../../api/chat.js"
import { FG } from "../../api/req.js"


const { proxy } = getCurrentInstance();

let contentPd = ref(0)                   // 聊天空白内容高度
let strHeight = computed(() => {
  return `  padding-bottom: ${contentPd.value}px;`
})

let isOpenMore = ref(false)       // 是否打开表情列表
let moveStatus = {
  open: 0,
  close: 1,
}
let isNeedMove = moveStatus.close            //判断收否需要上下滑动

let isFocus = ref(false)
let flagForRefresh = ref(false)   // 下拉刷新标志

let inputHeight = ref('height:38rpx ;')  // 输入框高度
let inputValue = ref('')          //输入内容

let heightForMore = ref('height:300rpx;') // 表情列表高度
let heightForInput = ref('bottom:env(safe-area-inset-bottom);') // 输入框定位高度
let layoutTopMove = ref("")
let layoutHeight = ref('height: 100%;')
//表情包列表
let scrollTop = ref(0)              // 滚动高度

let relation = false
//聊天记录
let msgList = reactive([])

let myID = 0
let friendID = 0
let remark = ''
let storeageHeight = uni.getStorageSync("heightForMore")

let selectItem = ref(0)    //选项索引

let taskUploadOrDownload = []
let scorllAnimation = ref(false) //添加滚动动画

let page = ref(1)

let emoji = reactive([])
let myAvatar = ref('')
let friendAvatar = ref('')


let loadingImg = ref({})


async function getEmji() {
  for (let index = 1; index <= 13; index++) {
    emoji.push(`${FG.baseUrl}/static/emoji/xiaoeyu${index}.jpg`)
  }
}
getEmji()

//跳转用户详细界面
function toUserInfo(user) {
  if (user == 'my') {
    uni.navigateTo({
      url: `/pages/user/user?userId=${myID}&friendStatus=200`,
    })
  } else {
    uni.navigateTo({
      url: `/pages/user/user?userId=${friendID}&friendStatus=200&remark=${remark}`,
    })
  }
}
//预览图形
function previewImage(url) {
  uni.previewImage({
    current: 0,
    urls: [url],
  })
}
async function downloadFile(data) {
  if (data.isLoading) {
    return
  }
  try {
    uni.showLoading()
    let url = `${FG.baseUrl}/getFile_static?filePath=${data.message}`
    let isFound = await fileIsFound({ filePath: data.message })
    if (isFound.status != 200) return new Error(isFound.msg)
    let a = document.createElement('a')
    a.href = url
    a.download = data.fileName
    setTimeout(() => {
      a.click()
    }, 100);
    uni.hideLoading()
  } catch (err) {
    uni.hideLoading()
    uni.showToast({
      title: `下载失败请稍后重试`,
      icon: 'error',
      duration: 1500
    })
  }
  // data.isLoading = true
  // data.progress = 0
  // taskUploadOrDownload.push('task')
  // getFile({
  //   filePath: data.message
  // }, (res) => {
  //   data.progress = res.progress
  //   if (data.progress == 100) {
  //     data.isLoading = false
  //   }
  // }).then((res) => {
  //   let tempFilePath = res.tempFilePath
  //   let a = document.createElement("a")
  //   a.href = tempFilePath
  //   a.download = data.fileName
  //   a.click()
  //   taskUploadOrDownload.pop()
  // }).catch((err) => {
  //   taskUploadOrDownload.pop()
  //   uni.showToast({
  //     title: `下载失败请稍后重试`,
  //     icon: 'error',
  //     duration: 1500
  //   })
  //   data.isLoading = false
  //   data.progress = 0
  // })
}
//滚动顶部处理函数
function reachUp(e) {
  flagForRefresh.value = true
  setTimeout(() => {
    page.value = page.value + 1
    handlerMsgList(page.value).then(() => {
      setTimeout(() => {
      }, 100)
    })
    flagForRefresh.value = false
  }, 1000)
}

// 输入文本换行处理函数 
function changeLayout(e) {
  if (e.detail.lineCount < 6) {
    inputHeight.value = `height:${e.detail.lineCount * 38}rpx ;`
  }
  nextTick(() => {
    observeElementHeight()
    if (inputValue.value.length !== 0) {
      setTimeout(() => {
        scrollTop.value = 0
        nextTick(() => {
          scrollToBotom()
        })
      }, 80)
    }
  })
}
// 键盘高度改变处理函数
function keyBoardHeightChange(e) {

}

//获取焦点处理函数
function focusHandler(e) {
  if (isNeedMove == moveStatus.open) {
    isNeedMove = moveStatus.close
    uni.hideKeyboard()
    setTimeout(() => {
      isFocus.value = true
    }, 100)
  } else {
    isNeedMove = moveStatus.open
  }
  if (isOpenMore.value == true) {
    layoutTopMove.value = `top:calc(44px);`
    heightForInput.value = `bottom:env(safe-area-inset-bottom);`
  }
  isOpenMore.value = false //关闭表情列表标志
}
//失去焦点处理函数
function blurHandler(e) {
  uni.hideKeyboard()
  isFocus.value = false
}

//打开表情列表
function openMore(num) {
  if (num != null) {
    selectItem.value = num
  }
  isOpenMore.value = !isOpenMore.value
  let height = storeageHeight
  if (isOpenMore.value) {
    heightForInput.value = `bottom:${height}rpx;`
    layoutTopMove.value = `top:calc(44px  - ${height}rpx);`

    if (isNeedMove == moveStatus.close) {
      isNeedMove = moveStatus.open
    }
  } else {
    layoutTopMove.value = `top:calc(44px );`
    heightForInput.value = `bottom:env(safe-area-inset-bottom);`

    setTimeout(() => {
      isFocus.value = true
    }, 80)
  }
}
//在输入内容里光标前添加表情
function selectEmoji(index) {
  let data = {
    uid: myID,
    fid: friendID,
    msg: emoji[index],
    type: 1,
    isFriend: relation,
    size: 10000
  }
  sendMsg(data)
}


//敲击回车键发生消息
function confirm(e) {
  if (inputValue.value.trim() == "") {
    return inputValue.value = ""
  }
  let data = {
    uid: myID,
    fid: friendID,
    msg: inputValue.value.trim(),
    type: 0,
    isFriend: relation
  }
  inputValue.value = ""
  sendMsg(data)
}

//获取输入区域的高度
function observeElementHeight() {
  // 创建选择器查询对象
  const query = uni.createSelectorQuery().in(proxy);

  // 选择需要监听高度变化的元素，假设这里有一个id为elementId的元素
  query.select('.input')
    .boundingClientRect(data => {
      // data 包含了元素的布局信息，如 height, width 等
      contentPd.value = data.height + 10
    })
    .exec();
}
function observePageInfo(className) {
  return new Promise((resolve, reject) => {
    try {
      // 创建选择器查询对象
      const query = uni.createSelectorQuery().in(proxy);
      // 选择需要监听高度变化的元素，假设这里有一个id为elementId的元素
      query.select(`.${className}`)
        .boundingClientRect(data => {
          resolve(data)
        })
        .exec();
    } catch {
      reject()
    }
  })
}
//滚动到底部
function scrollToBotom() {
  scrollTop.value = 999999999
}

//点击其他关闭表情列表
function topClick(e) {
  if (isNeedMove == moveStatus.open) {
    isNeedMove = moveStatus.close
  }
  if (isOpenMore.value) {
    isOpenMore.value = !isOpenMore.value
    layoutTopMove.value = `top:calc(44px);`
    heightForInput.value = `bottom:env(safe-area-inset-bottom);`
  }
  isNeedMove = moveStatus.close
}


// 更多选项的选择
function select(num) {
  selectItem.value = num
}

//横向滑动更多切换选项
function swiperChange(e) {
  selectItem.value = e?.detail?.current
}
/**
 * 格式化字节单位
 * 将字节大小转换为更易读的格式，如KB, MB, GB等。
 * 
 * @param {number} bytes 待转换的字节大小
 * @param {number} decimals 小数点保留位数，默认为2
 * @returns {string} 格式化后的字节大小字符串
 */
function formatBytes(bytes, decimals = 2) {
  // 如果字节大小为0，直接返回"0 Bytes"
  if (bytes === 0) return '0 Bytes';

  // 定义每种单位对应的字节大小
  const k = 1024;
  // 确定小数点保留位数，如果小于0则保留0位
  const dm = decimals < 0 ? 0 : decimals;
  // 定义单位数组
  const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];

  // 计算当前字节大小应属于哪个单位
  const i = Math.floor(Math.log(bytes) / Math.log(k));

  // 返回格式化后的字节大小字符串
  return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
}
function openFunction(value) {
  switch (value) {
    case 'tupian':
      uni.chooseImage({
        count: 1,
        sizeType: ['original', 'compressed'],
        sourceType: ['album'],
        success: async ({ tempFilePaths, tempFiles }) => {
          let type = tempFiles[0].type.split('/')[0]
          if (type == 'image') {
            let data = {
              userID: myID,
              friendID: friendID,
              message: tempFilePaths[0],
              type: 1,
              isFriend: relation,
              time: new Date().getTime(),
              _id: new Date().getTime(),
              fileName: tempFiles[0].name,
              size: tempFiles[0].size,
            }
            msgList.push({
              type: 'msg',
              data
            })
            loadingImg.value[msgList.length - 1] = true
            //滑动到底部
            scrollTop.value = 0
            nextTick(() => {
              scrollToBotom()
            })
            try {
              let data = {
                uid: myID,
                fid: friendID,
                msg: '',
                type: 1,
                isFriend: relation,
                size: tempFiles[0].size
              }
              taskUploadOrDownload.push('task')
              let res = await uploadFile({
                file: tempFiles[0]
              })
              taskUploadOrDownload.pop()
              let baseUrl = FG.baseUrl
              let url = res.fileUrl.split('/').slice(1).join('/')
              data.msg = `${baseUrl}/static/${url}`
              data.type = 1
              sendMsg(data)
            } catch {
              taskUploadOrDownload.pop()
              uni.showToast({
                title: '上传失败',
                icon: 'error',
                mask: true,
                duration: 500
              })
            }
          } else {
            uni.showToast({
              title: '请选择图片格式文件',
              icon: 'error',
              duration: 1000
            })
          }
        },
        fail: (error) => {
          uni.showToast({
            title: '选择文件失败',
            icon: 'error',
            mask: true
          })
        }
      })
      break
    case 'wenjian':
      uni.chooseFile({
        type: 'all',
        success: async ({ tempFilePaths, tempFiles }) => {
          let size = tempFiles[0].size
          if (size <= 1073741824 / 1024 * 100) {
            let suffixSet = new Set(['ai', 'avi', 'bmp', 'crd', 'csv', 'dll', 'doc', 'docx', 'dwg',
              'eps', 'exe', 'flv', 'gif', 'html', 'iso', 'java', 'jpg', 'mdb', 'mid', 'mov', 'mp3',
              'mp4', 'mpeg', 'pdf', 'ppt', 'png', 'ps', 'psd', 'pub', 'rar', 'raw', 'rss', 'svg', 'tiff', 'txt',
              'wav', 'wma', 'xml', 'xsl', 'zip'])
            let suffix = tempFiles[0].name.split('.').pop()
            let data = {
              userID: myID,
              friendID: friendID,
              message: '',
              type: 3,
              isFriend: relation,
              time: new Date().getTime(),
              _id: new Date().getTime(),
              size: tempFiles[0].size,
              isLoading: true,
              progress: 0,
              fileName: tempFiles[0].name,
              suffix: ''
            }

            if (suffixSet.has(suffix)) {
              data.suffix = suffix.toLocaleUpperCase()
            } else {
              data.suffix = `_`
            }
            msgList.push({
              type: 'msg',
              data
            })
            let index = msgList.length - 1
            //滑动到底部
            scrollTop.value = 0
            nextTick(() => {
              scrollToBotom()
            })
            try {
              let data = {
                uid: myID,
                fid: friendID,
                msg: '',
                type: 3,
                isFriend: relation,
                size: tempFiles[0].size
              }
              taskUploadOrDownload.push('task')
              let res = await uploadFile({
                file: tempFiles[0]
              }, (res) => {
                msgList[index].data.progress = res.progress
              })
              taskUploadOrDownload.pop()
              data.msg = res.fileUrl
              sendMsg(data)
            } catch {
              taskUploadOrDownload.pop()
              uni.showToast({
                title: '文件上传失败',
                icon: 'error',
                mask: true,
                duration: 500
              })
            }
          } else {
            uni.showToast({
              title: '请选择小于等于100M的文件',
              icon: 'error',
              duration: 1000
            })
          }
        },
        fail: (error) => {
          uni.showToast({
            title: '选择文件失败',
            icon: 'error',
            mask: true
          })
        }
      })
      break
    case 'paishe':
      uni.chooseImage({
        count: 1,
        sizeType: ['original', 'compressed'],
        sourceType: ['camera'],
        success: async ({ tempFilePaths, tempFiles }) => {
          let type = tempFiles[0].type.split('/')[0]
          if (type == 'image') {
            let data = {
              userID: myID,
              friendID: friendID,
              message: tempFilePaths[0],
              type: 1,
              isFriend: relation,
              time: new Date().getTime(),
              _id: new Date().getTime(),
              fileName: tempFiles[0].name,
              size: tempFiles[0].size,
              isLoading: true
            }
            msgList.push({
              type: 'msg',
              data
            })
            //滑动到底部
            scrollTop.value = 0
            nextTick(() => {
              scrollToBotom()
            })
            try {
              let data = {
                uid: myID,
                fid: friendID,
                msg: '',
                type: 1,
                isFriend: relation,
                size: tempFiles[0].size
              }
              taskUploadOrDownload.push('task')
              let res = await uploadFile({
                file: tempFiles[0]
              })
              taskUploadOrDownload.pop()
              let baseUrl = FG.baseUrl
              let url = res.fileUrl.split('/').slice(1).join('/')
              data.msg = `${baseUrl}/static/${url}`
              data.type = 1
              sendMsg(data)
            } catch {
              taskUploadOrDownload.pop()
              uni.showToast({
                title: '上传失败',
                icon: 'error',
                mask: true,
                duration: 500
              })
            }
          } else {
            uni.showToast({
              title: '请选择图片格式文件',
              icon: 'error',
              duration: 1000
            })
          }
        },
        fail: (error) => {
          uni.showToast({
            title: '选择文件失败',
            icon: 'error',
            mask: true
          })
        }
      })
      break
  }
}
//////////////////////////////////////////生命周期函数////////////////////////////////////////////
onLoad(async (data) => {
  uni.showLoading({
    mask: true,
  })
  myID = data.my
  friendID = data.target
  remark = data.remark
  uni.setNavigationBarTitle({
    title: remark
  })

  initWebsocket()
  await clearUnread({
    myId: myID,
    targetId: friendID
  })
  login(myID)
  let { data: dataF } = await getUserInfo({ id: friendID })
  let { data: dataM } = await getUserInfo({ id: myID })
  myAvatar.value = `${FG.baseUrl}/static/${dataM.img}`
  friendAvatar.value = `${FG.baseUrl}/static/${dataF.img}`
  await handlerMsgList(page.value)
  let { status } = await getRelation({ uid: myID, fid: friendID })
  if (status == 200) relation = true
  observeElementHeight()

  nextTick(() => {
    scrollTop.value = 0
    setTimeout(() => {
      scrollToBotom()
    }, 100)
    scorllAnimation.value = true
    uni.hideLoading()
  })
})
function handlerFileMsg(data) {
  let { message } = data
  let fileName_temp = message.split('/').pop()
  let suffix = fileName_temp.split('.').pop()
  let fileName = fileName_temp.split('-[]-').shift()
  let suffixSet = new Set(['ai', 'avi', 'bmp', 'crd', 'csv', 'dll', 'doc', 'docx', 'dwg',
    'eps', 'exe', 'flv', 'gif', 'html', 'iso', 'java', 'jpg', 'mdb', 'mid', 'mov', 'mp3',
    'mp4', 'mpeg', 'pdf', 'ppt', 'png', 'ps', 'psd', 'pub', 'rar', 'raw', 'rss', 'svg', 'tiff', 'txt',
    'wav', 'wma', 'xml', 'xsl', 'zip'])
  data.fileName = fileName + "." + suffix
  if (suffixSet.has(suffix)) {
    data.suffix = suffix.toLocaleUpperCase()
  } else {
    data.suffix = `_`
  }
  return data
}

async function handlerMsgList(page_) {
  let getMsgParams_m = {
    uid: myID,
    fid: friendID,
    page: page_,
    limit: 20
  }
  let data_ = []
  let { data } = await getMsgList(getMsgParams_m)
  data.sort((a, b) => a.time - b.time)
  for (let i = 0; i < data.length; i++) {
    if (i == 0) {
      data_.push({ data: data[i].time, type: "time", page: page.value })
      if (data[i].type == 3) {
        data[i] = handlerFileMsg(data[i])
      }
      data_.push({ data: data[i], type: "msg" })
      continue
    }
    if (data[i].time - data[i - 1].time >= 10 * 60 * 1000) {
      data_.push({ data: data[i].time, type: "time" })
      if (data[i].type == 3) {
        data[i] = handlerFileMsg(data[i])
      }
      data_.push({ data: data[i], type: "msg" })
    } else {
      if (data[i].type == 3) {
        data[i] = handlerFileMsg(data[i])
      }
      data_.push({ data: data[i], type: "msg" })
    }
  }
  if (msgList.length == 0) {
    for (let i = 0; i < data_.length; i++) msgList.push(data_[i])
  } else {
    for (let i = data_.length - 1; i >= 0; i--) msgList.unshift(data_[i])
  }
  return 2
}
onReady(() => {
  let windowsHeight = uni.getWindowInfo().windowHeight
  layoutHeight.value = `height:${windowsHeight}px;`
  let emojiListHeight = uni.getStorageSync('heightForMore')
  if (emojiListHeight) {
    heightForMore.value = `height:${emojiListHeight}rpx;`
  }
  // 接收数据
  uni.onSocketMessage(function (res) {
    let data = JSON.parse(res.data);
    let { msg } = data
    if (data.event === 'message') {
      if (msg.type == 1) {
        let name_temp = msg.message.split('/')
        let fileName_temp = name_temp[name_temp.length - 1].split('-[]-')
        let fileName = fileName_temp[0] + '.' + fileName_temp[fileName_temp.length - 1].split('.')[1]
        let index = undefined
        for (let i = msgList.length - 1; i >= 0; i--) {
          if (msgList[i].data?.fileName == fileName && msgList[i].data.type == 1) {
            index = i
            break
          }
        }
        if (index != undefined) {
          loadingImg.value[index] = false
          scrollTop.value = 0
          nextTick(() => {
            scrollToBotom()
          })
          return
        }
      }
      if (msg.type == 3) {
        if (msg.userID !== myID) {
          msg.isLoading = false
          msg.fileName = msg.message.split('/').pop().split('-[]-').shift() + '.' + msg.message.split('.').pop()
          msg.suffix = msg.message.split('.').pop().toLocaleUpperCase()
        } else {
          msg.isLoading = false
          msg.fileName = msg.message.split('/').pop().split('-[]-').shift() + '.' + msg.message.split('.').pop()
          msg.suffix = msg.message.split('.').pop().toLocaleUpperCase()
          let index = undefined
          for (let i = msgList.length - 1; i >= 0; i--) {
            if (msgList[i].data?.isLoading && msgList[i].data.type == 3 && msgList[i].data.fileName == msg.fileName) {
              index = i
              break
            }
          }
          if (index != undefined) {
            msgList[index].data.message = msg.message
            msgList[index].data.time = msg.time
            msgList[index].data._id = msg._id
            msgList[index].data.isLoading = false
          }
          nextTick(() => {
            scrollTop.value = 0
            scrollToBotom()
          })
          return
        }
      }
      let msgLast = msgList[msgList.length - 1]
      if (!msgLast) {
        msgList.push({ data: +msg.time, type: "time" })
        msgList.push({ data: msg, type: "msg" })
        return
      }
      if (msg.time - msgLast.data.time >= 10 * 60 * 1000) {
        msgList.push({ data: +msg.time, type: "time" })
        msgList.push({ data: msg, type: "msg" })
      } else {
        msgList.push({ data: msg, type: "msg" })
      }
    }
    scrollTop.value = 0
    nextTick(() => {
      scrollToBotom()
    })
  });
})

onBackPress(() => {
  if (taskUploadOrDownload.length > 0) {
    uni.showToast({
      title: '请不要刷新浏览器,否则上传或下载任务以及记录将被取消',
      icon: 'none',
      duration: 2000,
    })
  }
  uni.hideLoading()
})
onUnmounted(() => {
  closeSocket()
})
</script>

<style lang="scss" scoped>
.layout_top {
  --animeationTime: 0.2s;
  width: 100%;
  height: calc(100vh - 44px - env(safe-area-inset-top) - env(safe-area-inset-bottom));
  position: fixed;
  top: calc(44px);
  left: 0;
  transition: all var(--animeationTime);
}

.chatLayout {

  height: 100%;
  width: 100%;
  background-color: #eee;
  overflow: hidden;
  transition: all var(--animeationTime);
  will-change: height;

  .content {
    display: flex;
    flex-direction: column;
    overflow: auto;
    height: 100%;

    .chat_item {
      position: relative;
      display: flex;
      max-width: 100%;
      // margin: 30rpx 0;
      // margin-bottom: 30rpx;
      padding: 30rpx 0;

      .item_img {
        width: 80rpx;
        height: 80rpx;
        overflow: hidden;
        display: inline-block;
        border-radius: 50%;
        margin-right: 20rpx;
        margin-left: 20rpx;

        image {
          width: 100%;
          height: 100%;
        }
      }

      .item_content {
        // max-width: 70%;
        border-radius: 20rpx;
        height: auto;
        background-color: skyblue;

        text {
          display: inline-block;
          /* 确保text作为块级元素显示，以便宽度生效 */
          width: 100%;
          /* 或者设定一个具体的宽度值，例如 200px */
          white-space: normal;
          /* 允许文本正常换行 */
          word-wrap: break-word;
          /* 兼容旧版浏览器，允许长单词换行 */
          overflow-wrap: break-word;
          /* 新的标准属性，同样用于长单词换行 */
          text-wrap: wrap;
        }

        img,
        image {
          display: block;
          max-width: 100%;
          min-width: 80rpx;
          min-height: 80rpx;
        }
      }
    }

    .chat_item.right {
      .item_content {
        margin-left: auto;
      }
    }

    .chat_item.text {
      .item_content {
        padding: 20rpx;
      }
    }

    .chat_item.image {
      .item_content {
        padding: 0;
        position: relative;

        img {
          width: 15vmax;
          min-height: 40px;
        }
      }
    }

    .chat_item.image.right,
    .chat_item.image.left {

      /* HTML: <div class="loader"></div> */
      .loader {
        width: 36rpx;
        --b: 8rpx;
        aspect-ratio: 1;
        border-radius: 50%;
        padding: 1px;
        background: conic-gradient(#0000 10%, #f03355) content-box;
        -webkit-mask:
          repeating-conic-gradient(#0000 0deg, #000 1deg 20deg, #0000 21deg 36deg),
          radial-gradient(farthest-side, #0000 calc(100% - var(--b) - 1px), #000 calc(100% - var(--b)));
        -webkit-mask-composite: destination-in;
        mask-composite: intersect;
        animation: l4 1s infinite steps(10);
        position: absolute;
        right: -36rpx;
        bottom: -36rpx;
      }

      @keyframes l4 {
        to {
          transform: rotate(1turn)
        }
      }
    }

    .chat_item.image.left {

      .loader {
        left: -60rpx;
      }
    }


    .chat_item.file {

      .item_content {
        padding: 0;
        background-color: #fff;
        padding: 20rpx;
        display: flex;
        width: 70%;
        height: 200rpx;
        justify-content: space-between;
        align-items: center;

        .item_content_nameSize {
          flex: 1;
          padding: 10rpx;
          max-width: 75%;

          .name {
            display: -webkit-box;
            -webkit-line-clamp: 2;
            -moz-line-clamp: 2;
            -o-line-clamp: 2;
            line-clamp: 2;
            /* 指定行数，例如3行 */
            -webkit-box-orient: vertical;
            /* 设置或检索伸缩盒对象的子元素的排列方式 */
            overflow: hidden;
            text-overflow: ellipsis;

          }

          .size {
            font-size: 24rpx;
            color: #333;
          }
        }

        .item_content_type {
          width: 100rpx;
          height: 120rpx;
        }
      }
    }

    .chat_item.time {
      display: block;
      text-align: center;
      font-size: 26rpx;
      color: #aaa;
    }

    .bottom {
      width: 100%;
      height: 0px;
      transition: all var(--animeationTime);
    }
  }

  .input {
    width: 100%;
    overflow: hidden;
    min-height: 120rpx;
    position: fixed;
    bottom: env(safe-area-inset-bottom);
    left: 0;
    border-top: 1px solid #eee;
    background-color: #f9f9f9;
    display: flex;
    padding: 20rpx 20rpx;
    flex-direction: column;
    z-index: 999999999999999;
    transition: all var(--animeationTime);

    .input_item {
      width: 100%;
      display: flex;
      align-items: center;
      flex: 1;

      .send {
        background-color: #75C3FF;
        border-radius: 10%;
        padding: 5rpx 5rpx;
        color: #f9f9f9;
      }

      .input_text {
        flex: 1;
        background-color: #fff;
        padding: 10rpx 10rpx;
        height: 50rpx;
        font-size: 32rpx;
        line-height: 35rpx;
      }

      .input_text textarea:focus {
        border-bottom: 1px solid #ccc;
        background-color: red;
      }

      .iconfont {
        width: 60rpx;
        height: 60rpx;
        font-size: 40rpx;
        line-height: 60rpx;
        text-align: center;
      }

      .icon-emoji {
        font-size: 50rpx;
      }

      .icon-jianpan {
        font-size: 50rpx;
      }

      .icon-jia {
        font-size: 50rpx;
      }
    }
  }
}


.menu {
  margin-top: 10rpx;
  width: 100%;
  height: 0px;
  // opacity: 0;
  margin-top: 0;
  // position: fixed;
  transition: all var(--animeationTime);
  padding: 0 50rpx;
  margin-top: 20rpx;
  display: none;

  .menu_slection {
    height: 50rpx;
    margin-bottom: 40rpx;

    .slection_all {
      display: flex;

      .iconfont {
        border-radius: 20%;
        padding: 0 16rpx;
        height: 100%;
        font-size: 50rpx;
        line-height: 50rpx;
      }

      .iconfont.icon-shoucang {
        font-size: 50rpx;
      }

      .iconfont.icon-jia {
        font-size: 50rpx;
      }

      .iconfont.active {
        background-color: #eee;
        color: #75C3FF;
        transition: all var(--animeationTime);
      }
    }

  }

  .List_scroll {
    margin-top: 10rpx;
    width: 100%;
    height: calc(100% - 80px);

    .swiper-more {
      width: 100%;
      height: 100%;

      .emoji {
        width: 100%;

        .scroll_style {
          width: 100%;
          display: grid;
          grid-template-columns: repeat(4, 1fr);
          gap: 10rpx;
          align-items: center;
          justify-items: center;

          .scroll_item {

            img,
            image {
              width: 130rpx;
              height: 130rpx;
            }
          }
        }
      }

      .shoucang {
        background-color: pink;
      }

      .jia {
        .more-function {
          width: 100%;
          height: 100%;
          display: grid;

          grid-template-columns: repeat(4, 1fr);
          grid-template-rows: repeat(2, 1fr);
          grid-gap: 10rpx;

          .item {

            display: flex;
            justify-content: center;
            align-items: center;
            flex-direction: column;

            .item_box {
              width: 100rpx;
              display: flex;
              justify-content: center;
              align-items: center;
              flex-direction: column;

              .iconfont {
                width: 50rpx;
                height: 50rpx;
                font-size: 50rpx;
              }

              .text {
                margin-top: 6rpx;
                height: 50rpx;
                font-size: 26rpx;
              }
            }
          }
        }
      }
    }
  }
}

.menu.active {
  height: 300rpx;
  opacity: 1;
  display: block;
}

.debug {
  // height: 100vh;
  // width: 100vw;
  position: fixed;
  left: 50%;
  bottom: 50%;
  transform: translate(-50%, 50%);
  color: red;
  padding: 10rpx;
  // background-color: red;
  // z-index: 9999999999999999;
}
</style>